const path = require('path')
const webpack = require('webpack')
const os = require('os')
const threads = os.cpus().length
const TerserPlugin = require('terser-webpack-plugin')
const CompressionPlugin = require('compression-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin // 添加打包分析
const { whenDev, whenProd } = require('@craco/craco')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const ESLintWebpackPlugin = require('eslint-webpack-plugin')

module.exports = {
  webpack: {
    plugins: [
      ...whenProd(() => [ // 生产环境下plugin的配置
        new TerserPlugin({
          terserOptions: {
            compress: {
              drop_console: process.env.NODE_ENV === 'production'
            }
          }
        }),

        new CompressionPlugin({
          algorithm: 'gzip', // 使用gzip压缩
          test: /\.js(\?.*)?$/i, // 压缩js文件
          threshold: 10240, // 只有大于10240字节的文件会被压缩
          minRatio: 0.8, // 压缩率达到0.8才会被应用
          deleteOriginalAssets: false, // 是否删除原文件
        }),

        new BundleAnalyzerPlugin() // 打包的时候 才显示打包分析
      ], []),
      
      new webpack.ProvidePlugin({
        jquery: '$'
      }),
    ],

    // 按需导入antd
    babel: {
      plugins: [
        ['import', {libraryName: 'antd', libraryDirectory: 'es', style:'css'}, 'antd']
      ]
    },
    
    // 要在tsconfig.json里面同步配置
    // "baseUrl": ".",   "paths": {"@/*": ["src/*"], "@/assets*": ["src/assets/*"]}
    alias: {
      "@": path.resolve(__dirname, 'src'), 
      "@assets": path.resolve(__dirname, 'src/assets') 
    },

    // 写法是对的, 但报404的错误
    devServer: {
      port: 3000,
      host: '0.0.0.0', // 允许外部ip访问
      https: false, // 启用https
      open: true,
      hot: true,

      proxy: {
        '/api': {
          target: 'http://localhost/data.json',
          ws: true,
          changeOrigin: true,
          pathRewrite: {
            '^/api': ''
          }
        }
      }
    },

    configure: (webpackConfig, {env, paths}) => {
      webpackConfig.devtool = false
      webpackConfig.output.filename = 'js/[name].[chunkhash:3].js'
      webpackConfig.output.chunkFilename = 'js/[name].[chunkhash:3].js'
      webpackConfig.module.rules[1].oneOf[3].options.plugins.push('@babel/plugin-transform-runtime') //减少babel体积
      webpackConfig.externals = { jquery: '$'}

     
      // 最开始使用的方法: webpackConfig.plugins[8].options.filename = 'css/[name].[contenthash:2].css'
      webpackConfig.plugins.map((plugin) => {
        whenProd(() => {
          if (plugin instanceof MiniCssExtractPlugin) {
            plugin.options.filename = 'css/[name].[contenthash:3].css'
            plugin.options.chunkFilename = 'css/[name].[contenthash:3].css'
          } else if(plugin instanceof ESLintWebpackPlugin) {
            plugin.threads = threads
          }
        })
        return plugin
      })

      webpackConfig.module.rules.push(
        {
          test: /\.(woff|woff2|eot|ttf|otf)$/i, type: 'asset/resource',
          parser: {dataUrlCondititon: { maxSize: 10 * 1024 }}, // 小于10kb 转为base64
          generator: { filename: 'fonts/[name].[contenthash:1][ext]' } 
        },

        // 压缩图片image-webpack-loader配置报错了, 在vue中却有效
        {
          test: [ /\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/ ],type: 'asset',
          parser: {dataUrlCondition: { maxSize: 50 * 1024 }},
          generator: { filename: 'img/[name].[contenthash:1][ext]' },
        },
        {
          test:/.(mp4|webm|ogg|mp3|wav|flac|aac)$/, type: "asset",
          parser: {dataUrlCondition: { maxSize: 10 * 1024 }},
          generator:{ filename:'media/[name].[contenthash:1][ext]'}
        }
      )

      webpackConfig.optimization = {
        splitChunks: {
          cacheGroups: {
            axios: {
              name: 'axios',
              test:/[\\/]node_modules[\\/]axios[\\/]/,
              chunks: 'all',
              minSize: 0,
              minChunks: 1,
              priority: 5
            },
            jquery: {
              name: 'jquery',
              test:/[\\/]node_modules[\\/]jquery[\\/]/,
              chunks: 'all',
              minSize: 0,
              minChunks: 1,
              priority: 5
            },
            hooks: {
              name: 'hooks',
              test: /[\\/]src[\\/]hooks[\\/]/,
              chunks: 'all',
              minSize: 0,
              minChunks: 1,
              priority: 5
            }
          }
        },
  
        runtimeChunk: {
          name: (entrypoint) => `runtime-${entrypoint.name}.js`
        }
      }
      return webpackConfig
    }
  } 
}